package org.study.mybatisplus.dynamic.boot.controller;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.study.mybatisplus.dynamic.boot.dto.*;
import org.study.mybatisplus.dynamic.boot.model.IotLog;
import org.study.mybatisplus.dynamic.boot.service.DeviceService;
import org.study.mybatisplus.dynamic.boot.vo.*;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 设备管理
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2024年10月08日
 */
@Slf4j
@RestController
@RequestMapping("/device")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DeviceController {
    private final DeviceService deviceService;

    /**
     * 保存设备
     */
    @PostMapping("/save")
    public Boolean deviceSave(@Validated @RequestBody DeviceSaveDTO deviceSaveDTO) {
        return deviceService.deviceSave(deviceSaveDTO);
    }

    /**
     * 删除设备
     */
    @PostMapping("/remove/{id}")
    public Boolean deviceRemove(@PathVariable("id") long id) {
        return deviceService.deviceRemove(id);
    }

    /**
     * 设备分页列表
     */
    @GetMapping("/list")
    public IPage<DeviceVO> deviceList(@RequestParam Long projectId, @RequestParam(required = false) String deviceName,
                                      @RequestParam Integer page, @RequestParam Integer size) {
        return deviceService.deviceList(new Page<>(page, size), projectId, deviceName);
    }

    /**
     * 设备详情
     */
    @GetMapping("/detail/{deviceId}")
    public DeviceVO deviceDetail(@PathVariable("deviceId") Long deviceId) {
        return deviceService.deviceDetail(deviceId);
    }

    /**
     * 根据设备点位重新创建时序数据库中的表(注意：会先删除原来的表及其数据)
     */
    @GetMapping("/create/tsdbTable1")
    public Boolean property2Tsdb1(@RequestParam(value = "deviceId", required = false) Long deviceId) {
        return deviceService.property2Tsdb1(deviceId);
    }

    /**
     * 根据设备点位重新创建时序数据库中的表(注意：会先删除原来的表及其数据)
     */
    @GetMapping("/create/tsdbTable2")
    public Boolean property2Tsdb2(@RequestParam(value = "deviceId", required = false) Long deviceId) {
        return deviceService.property2Tsdb2(deviceId);
    }

    /**
     * 保存属性
     */
    @PostMapping("/property/save")
    public Boolean devicePropertySave(@Validated @RequestBody DevicePropertySaveDTO devicePropertySaveDTO) {
        return deviceService.devicePropertySave(devicePropertySaveDTO);
    }

    /**
     * 删除属性
     */
    @PostMapping("/property/remove")
    public Boolean devicePropertyRemove(@Validated @RequestBody IdAuthDTO idAuthDTO) {
        return deviceService.devicePropertyRemove(idAuthDTO);
    }

    /**
     * 设备属性分页列表
     */
    @GetMapping("/property/list")
    public IPage<DevicePropertyVO> devicePropertyList(@RequestParam Long deviceId, @RequestParam(required = false) String propertyName,
                                                      @RequestParam Integer page, @RequestParam Integer size) {
        return deviceService.devicePropertyList(new Page<>(page, size), deviceId, propertyName);
    }

    /**
     * 一键导入设备属性(会自动创建设备)
     */
    @PostMapping("/import/all/{projectId}")
    public Boolean deviceImport(@PathVariable("projectId") Long projectId,
                                @RequestParam(value = "powerStationId", required = false) Long powerStationId,
                                @RequestParam("file") MultipartFile file) {
        return deviceService.deviceImport(projectId, powerStationId, file);
    }

    /**
     * 一键导入设备属性(导入到已有设备下)
     */
    @PostMapping("/import/property/{deviceId}")
    public Boolean propertyImport(@PathVariable("deviceId") Long deviceId,
                                  @RequestParam("file") MultipartFile file) {
        return deviceService.propertyImport(deviceId, file);
    }

    /**
     * 导出设备属性
     */
    @GetMapping("/exportDeviceProperty")
    public void exportDeviceProperty(@RequestParam(value = "deviceId", required = false) Long deviceId,
                                     HttpServletResponse response) throws IOException {
        List<DevicePropertyExportVO> list = deviceService.exportDeviceProperty(deviceId);
        try (ExcelWriter writer = ExcelUtil.getWriter(true)) {
            // 写出Bean数据：字段名称为表头，通过注解设置自定义表头
            writer.write(list, true);
            String filenameSuffix = "all";
            if (deviceId != null) {
                filenameSuffix = deviceId.toString();
            }
            // fileName是弹出下载对话框的文件名，名称包含中文的话请自行编码
            response.setHeader("Content-Disposition", "attachment;filename=device_property_" + filenameSuffix + ".xlsx");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            // out为OutputStream，需要写出到的目标流
            try (ServletOutputStream out = response.getOutputStream()) {
                writer.flush(out, true);
            }
        }
    }

    /**
     * 为所有告警设备的属性生成告警配置
     */
    @PostMapping("/createAlarmConfig")
    public Boolean createAlarmConfig4AllDevice() {
        return deviceService.createAlarmConfig4AllDevice();
    }

    /**
     * 查询设备属性实时值
     */
    @PostMapping("/queryCurrentValue")
    public List<QueryCurrentValueVO> queryCurrentValue(@Validated @RequestBody QueryCurrentValueDTO queryCurrentValueDTO) {
        return deviceService.queryCurrentValue(queryCurrentValueDTO);
    }

    /**
     * 查询设备属性历史数据
     */
    @PostMapping("/queryHistoryValue")
    public QueryHistoryValueVO queryHistoryValue(@Validated @RequestBody QueryHistoryValueDTO queryHistoryValueDTO) {
        return deviceService.queryHistoryValue(queryHistoryValueDTO);
    }

    /**
     * 导出设备属性历史数据
     */
    @PostMapping("/exportHistoryValue")
    public Boolean exportHistoryValue(HttpServletResponse response,
                                      @Validated @RequestBody QueryHistoryValueDTO queryHistoryValueDTO) {
        deviceService.exportHistoryValue(response, queryHistoryValueDTO);
        return true;
    }

    /**
     * 设备日志列表
     */
    @GetMapping("/log/list")
    public IPage<IotLog> logList(@RequestParam Long projectId, @RequestParam Long deviceId,
                                 @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime,
                                 @RequestParam Integer page, @RequestParam Integer size) {
        return deviceService.logList(new Page<>(page, size), projectId, deviceId, startTime, endTime);
    }

    /**
     * 设备数量及在线状态
     */
    @GetMapping("/panel/count")
    public Map<String, String> deviceCount(@RequestParam Long projectId) {
        return deviceService.productCount(projectId);
    }

    /**
     * 设备消息数量
     */
    @GetMapping("/panel/deviceMsg")
    public Map<String, String> deviceCountMsg(@RequestParam Long projectId, @RequestParam Long deviceId) {
        return deviceService.deviceMsg(projectId, deviceId);
    }
}
